/*
 * SPDX-FileCopyrightText: 2024 Andrew Gunnerson
 * SPDX-License-Identifier: GPL-3.0-only
 */

package com.sanji.audio_test.rule

import android.content.Context
import android.os.Bundle
import android.view.View
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.sanji.audio_test.R

/**
 * 录音规则列表布局管理器
 * 用于管理录音规则列表的布局和无障碍操作
 * @param context 上下文
 * @param globalAdapter 全局适配器
 */
internal class RecordRulesLayoutManager(
    context: Context,
    private val globalAdapter: ConcatAdapter,
) : LinearLayoutManager(context) {
    // 向上移动操作
    private val actionMoveUp = AccessibilityNodeInfoCompat.AccessibilityActionCompat(
        R.id.record_rule_drag_move_up,
        "Move rule up",
    )
    // 向下移动操作
    private val actionMoveDown = AccessibilityNodeInfoCompat.AccessibilityActionCompat(
        R.id.record_rule_drag_move_down,
        "Move rule down",
    )
    // 移除操作
    private val actionRemove = AccessibilityNodeInfoCompat.AccessibilityActionCompat(
        R.id.record_rule_swipe_remove,
        "Remove rule",
    )

    /**
     * 获取录音规则适配器和位置
     * @param globalPosition 全局位置
     * @return 录音规则适配器和位置的配对，如果找不到则返回null
     */
    private fun getRecordRuleAdapterAndPosition(globalPosition: Int):
            Pair<RecordRulesAdapter, Int>? {
        val pair = globalAdapter.getWrappedAdapterAndPosition(globalPosition)
        val adapter = pair.first

        return if (adapter is RecordRulesAdapter) {
            adapter to pair.second
        } else {
            null
        }
    }

    /**
     * 为项目初始化无障碍节点信息
     */
    override fun onInitializeAccessibilityNodeInfoForItem(
        recycler: RecyclerView.Recycler,
        state: RecyclerView.State,
        host: View,
        info: AccessibilityNodeInfoCompat,
    ) {
        super.onInitializeAccessibilityNodeInfoForItem(recycler, state, host, info)

        val (adapter, position) = getRecordRuleAdapterAndPosition(getPosition(host)) ?: return

        // 添加可执行的无障碍操作
        if (canMoveUp(adapter, position)) {
            info.addAction(actionMoveUp)
        }
        if (canMoveDown(adapter, position)) {
            info.addAction(actionMoveDown)
        }
        if (canRemove(adapter, position)) {
            info.addAction(actionRemove)
        }
    }

    /**
     * 执行项目的无障碍操作
     */
    override fun performAccessibilityActionForItem(
        recycler: RecyclerView.Recycler,
        state: RecyclerView.State,
        view: View,
        action: Int,
        args: Bundle?,
    ): Boolean {
        val adapterAndPosition = getRecordRuleAdapterAndPosition(getPosition(view))
        if (adapterAndPosition != null) {
            val (adapter, position) = adapterAndPosition

            when (action) {
                actionMoveUp.id -> if (canMoveUp(adapter, position)) {
                    adapter.onRuleMove(position, position - 1)
                    return true
                }
                actionMoveDown.id -> if (canMoveDown(adapter, position)) {
                    adapter.onRuleMove(position, position + 1)
                    return true
                }
                actionRemove.id -> if (canRemove(adapter, position)) {
                    adapter.onRuleRemove(position)
                    return true
                }
            }
        }

        return super.performAccessibilityActionForItem(recycler, state, view, action, args)
    }

    /**
     * 检查是否可以向上移动
     * @param adapter 录音规则适配器
     * @param position 当前位置
     * @return 是否可以向上移动
     */
    private fun canMoveUp(adapter: RecordRulesAdapter, position: Int) = position > 0
            && !adapter.isDefaultRule(position) && !adapter.isDefaultRule(position - 1)

    /**
     * 检查是否可以向下移动
     * @param adapter 录音规则适配器
     * @param position 当前位置
     * @return 是否可以向下移动
     */
    private fun canMoveDown(adapter: RecordRulesAdapter, position: Int) = position < itemCount - 1
            && !adapter.isDefaultRule(position) && !adapter.isDefaultRule(position + 1)

    /**
     * 检查是否可以移除
     * @param adapter 录音规则适配器
     * @param position 当前位置
     * @return 是否可以移除
     */
    private fun canRemove(adapter: RecordRulesAdapter, position: Int) =
        !adapter.isDefaultRule(position)
}